import React, { useRef } from "react";
import { useState } from "react";
import { Switch, message } from "antd";
import store from "store";

import {
  AudioOutlined,
  AudioMutedOutlined,
  CarOutlined,
} from "@ant-design/icons";
import { useDebounceEffect, useUnmount } from "ahooks";

export default function AudioPlayer({ url, connectType, onMicphoneChange }) {
  const audioEl = useRef(null);
  const wsRef = useRef(null);
  const mediaSourceRef = useRef(null);
  const [enabled, setEnabled] = useState(
    // window.MediaSource
    //   ? store.get("audio-enabled") === undefined
    //     ? true
    //     : false
    //   : false
    false
  );
  const [src, setSrc] = useState(null);

  useUnmount(() => {
    // 清理WebSocket连接
    if (wsRef.current) {
      wsRef.current.close();
      wsRef.current = null;
    }
    // 清理MediaSource
    if (mediaSourceRef.current) {
      try {
        mediaSourceRef.current.endOfStream();
      } catch (e) {
        // MediaSource可能已经关闭
      }
      mediaSourceRef.current = null;
    }
    // 清理URL对象
    if (src) {
      URL.revokeObjectURL(src);
    }
  });

  useDebounceEffect(
    () => {
      if (connectType === "ws") {
        if (!audioEl.current || !enabled) return;
        if (!window.MediaSource) {
          message.warn("移动版的 safari 浏览器暂不支持收听声音 😢");
          setTimeout(() => {
            setEnabled(false);
          }, 1000);
          return;
        }
        const mediaSource = new MediaSource();
        mediaSourceRef.current = mediaSource;
        let buffer = [];
        let sourceBuffer = null;
        let intervalId = null;
        
        function sourceopen() {
          try {
            sourceBuffer = mediaSource.addSourceBuffer(
              // "audio/webm"
              "audio/mpeg"
            );
            
            // 现在sourceBuffer已初始化，可以启动定时器
            intervalId = setInterval(() => {
              if (buffer.length && sourceBuffer && !sourceBuffer.updating) {
                sourceBuffer.appendBuffer(buffer.shift());
              }
            }, 10);
          } catch (error) {
            console.error('Failed to add source buffer:', error);
            setEnabled(false);
            return;
          }

          function onAudioLoaded({ data }) {
            if (sourceBuffer && !sourceBuffer.updating) {
              buffer.push(data);
              if (audioEl.current && audioEl.current.buffered.length) {
                const bufferTime =
                  audioEl.current.buffered.end(0) - audioEl.current.currentTime;
                const playbackRate = 1 + (bufferTime - 0.8) * 1.2;
                if (playbackRate < 0) {
                  audioEl.current.playbackRate = 0.5;
                } else if (playbackRate > 3) {
                  audioEl.current.playbackRate = 3;
                } else {
                  audioEl.current.playbackRate = playbackRate;
                }
              }
            }
          }

          const ws = new WebSocket(url);
          wsRef.current = ws;
          ws.binaryType = "arraybuffer";
          ws.addEventListener("message", onAudioLoaded);

          ws.addEventListener("open", () => {
            setEnabled(true);
          });
          ws.addEventListener("close", () => {
            setEnabled(false);
          });
        }

        mediaSource.addEventListener("sourceopen", sourceopen);
        setSrc(URL.createObjectURL(mediaSource));

        return function () {
          // 清理定时器
          if (intervalId) {
            clearInterval(intervalId);
          }
          // 清理WebSocket
          if (wsRef.current) {
            wsRef.current.close();
            wsRef.current = null;
          }
          // 清理MediaSource
          if (mediaSourceRef.current) {
            mediaSourceRef.current.removeEventListener("sourceopen", sourceopen);
            try {
              if (mediaSourceRef.current.readyState === 'open') {
                mediaSourceRef.current.endOfStream();
              }
            } catch (e) {
              console.warn('MediaSource cleanup error:', e);
            }
          }
        };
      } else {
        onMicphoneChange(enabled);
      }
    },
    [audioEl, enabled, url, connectType, onMicphoneChange],
    { wait: 500 }
  );

  return (
    <div>
      <audio ref={audioEl} src={src} autoPlay></audio>
      <Switch
        checked={enabled}
        onChange={(v) => {
          setEnabled(v);
          store.set("audio-enabled", v);
        }}
        checkedChildren={
          <>
            <CarOutlined /> <AudioOutlined />
          </>
        }
        unCheckedChildren={
          <>
            <CarOutlined /> <AudioMutedOutlined />
          </>
        }
      />
    </div>
  );
}
